package bookhive;

import java.util.Enumeration;
import java.util.Properties;

import net.jxta.discovery.DiscoveryService;
import net.jxta.document.Advertisement;
import net.jxta.peer.PeerID;
import net.jxta.peergroup.PeerGroup;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.ModuleSpecAdvertisement;
import net.jxta.protocol.PipeAdvertisement;

public abstract class LibraryPeer extends Thread {

	protected static String servicePipeName = "WorldCatalog:CatalogPipe";

	protected static String servicePipeType = PipeService.PropagateType;

	protected static final String ModuleSpecName = "JXTASPEC:wcCatalog-SPEC";

	protected PeerGroup group;

	protected PipeService pipes;

	protected DiscoveryService discovery;

	private int MAXRETRIES = 10;

	private long WaitingTime = 4000;

	protected Properties catalogProperties;

	public LibraryPeer(PeerGroup pg) {
		catalogProperties = new Properties();
		group = pg;
		boolean connected = pg.getRendezVousService().isConnectedToRendezVous();
		if (connected)
			System.out.println("connected to " + pg.getPeerGroupName()
					+ " RDV.");
		else
			System.out.println("not connected to " + pg.getPeerGroupName()
					+ " RDV.");

	}

	public void setCatalogProperties(Properties p) {
		catalogProperties = p;
	}

	public PeerID getPeerID() {
		return group.getPeerID();
	}

	protected Advertisement findAdv(String advType, String attr, String val,
			boolean localOnly) {

		Enumeration eee = null;
		// System.out.println("Looking for " + advType + ", please wait...");
		// First look in the local storage
		try {
			eee = discovery.getLocalAdvertisements(DiscoveryService.ADV, attr,
					val);

		} catch (Exception e) {
		}

		if ((eee != null) && (eee.hasMoreElements())) {
			Advertisement adv = null;
			while (eee.hasMoreElements()) {
				try {
					adv = (Advertisement) eee.nextElement();
					return adv;
				} catch (Exception e) {
					continue;
				}
			} // while
		} // if

		if (localOnly)
			return null;

		System.out.println("   cannot find it locally, trying remote");
		// Now, search remote
		discovery.getRemoteAdvertisements(null, DiscoveryService.ADV, attr,
				val, 2, null);

		// Wait a bit in order to get an answer.
		int i = 0;
		while (true) {
			try {
				if (i > MAXRETRIES) {
					System.out.print(".");
					break;
				}
				Thread.sleep(WaitingTime);
				i++;
			} catch (Exception e) {
			}
			System.out.println("");
			// Look in the local storage again
			try {
				eee = discovery.getLocalAdvertisements(DiscoveryService.ADV,
						attr, val);

				if ((eee != null) && (eee.hasMoreElements())) {
					Advertisement adv = null;

					while (eee.hasMoreElements()) {
						try {
							adv = (Advertisement) eee.nextElement();
							return adv;
						} catch (Exception e) {
							continue;
						}
					} // while
				}

				discovery.getRemoteAdvertisements(null, DiscoveryService.ADV,
						attr, val, 2, null);

			} catch (Exception e) {
			}
		}
		return null;
	}

	protected PipeAdvertisement findPipeAdv() {

		return (PipeAdvertisement) findAdv("PipeAdvertisement", "Name",
				servicePipeName, true);
	}

	protected ModuleSpecAdvertisement findModuleSpecAdv() {
		return (ModuleSpecAdvertisement) findAdv("ModuleSpecAdvertisement",
				"Name", ModuleSpecName, false);
	}
}
